package net.posick.ws.http;

import java.io.IOException;

import net.posick.ws.Constants;

import org.apache.http.HttpException;
import org.apache.http.protocol.HttpRequestHandler;

import android.app.Service;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class HTTPServerService extends Service
{
    public static final String LOG_TAG = Constants.LOG_TAG + "." + HTTPServerService.class.getSimpleName();
    
    
    // Binder given to clients
    private final IBinder mBinder = new HTTPServerServiceBinder();
    
    /**
     * Class used for the client Binder. Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class HTTPServerServiceBinder extends Binder
    {
        public HTTPServerService getService()
        {
            // Return this instance of LocalService so clients can call public methods
            return HTTPServerService.this;
        }
    }
    
    protected HTTPServer httpServer;
    
    
    @Override
    public IBinder onBind(Intent intent)
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onBind()");
        return mBinder;
    }
    
    
    @Override
    public void onCreate()
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onCreate()");
        
        super.onCreate();
        
        httpServer = new HTTPServer(this);
        httpServer.start();
    }
    
    
    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onConfigurationChanged()");
        super.onConfigurationChanged(newConfig);
    }
    
    
    @Override
    public void onDestroy()
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onDestroy()");
        try
        {
            httpServer.close();
        } catch (IOException e)
        {
            Log.e(LOG_TAG, "Error executing \"" + getClass().getSimpleName() + ".onDestroy()\" - " + e.getMessage(), e);
        }
        httpServer = null;
        super.onDestroy();
    }
    
    
    @Override
    public void onLowMemory()
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onLowMemory()");
        super.onLowMemory();
    }
    
    
    @Override
    public void onRebind(Intent intent)
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onRebind()");
        super.onRebind(intent);
    }
    
    
    @Override
    public boolean onUnbind(Intent intent)
    {
        Log.i(LOG_TAG, getClass().getSimpleName() + ".onUnbind()");
        return super.onUnbind(intent);
    }
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        return START_STICKY;
    }
    
    
    public HttpRequestHandler lookup(String pattern)
    {
        HTTPServer httpServer = this.httpServer;
        if (httpServer != null)
        {
            return httpServer.lookup(pattern);
        } else
        {
            return null;
        }
    }
    
    
    public String register(String pattern, HttpRequestHandler handler)
    throws HttpException
    {
        HTTPServer httpServer = this.httpServer;
        if (httpServer != null)
        {
            return httpServer.register(pattern, handler);
        } else
        {
            throw new HttpException("Cannot execute method, HTTPServer closed.");
        }
    }
    
    
    public void unregister(String pattern)
    throws HttpException
    {
        HTTPServer httpServer = this.httpServer;
        if (httpServer != null)
        {
            httpServer.unregister(pattern);
        } else
        {
            throw new HttpException("Cannot execute method, HTTPServer closed.");
        }
    }
}
